package com.opgea.tutor.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.opgea.tutor.dao.StudentDAO;
import com.opgea.tutor.domain.entities.Address;
import com.opgea.tutor.domain.entities.Email;
import com.opgea.tutor.domain.entities.Phone;
import com.opgea.tutor.domain.entities.Student;
import com.opgea.tutor.service.StudentService;
import com.opgea.tutor.web.dto.AddressDTO;
import com.opgea.tutor.web.dto.EmailDTO;
import com.opgea.tutor.web.dto.PhoneDTO;
import com.opgea.tutor.web.dto.StudentDTO;

@Service
@Transactional
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentDAO studentDAO;

    @Override
    public StudentDTO create(StudentDTO studentDTO) {
	if (studentDTO.getId() == 0) {
	    Student student = new Student();
	    Address address = new Address();
	    student.setAddress(address);
	    studentDTO.unmarshall(student);
	    studentDAO.create(student);
	    studentDTO.marshall(student);
	    return studentDTO;
	} else {
	    return update(studentDTO);
	}
    }

    @Override
    public StudentDTO update(StudentDTO studentDTO) {
	Student student = studentDAO.find(studentDTO.getId());
	studentDTO.unmarshall(student);
	studentDAO.update(student);
	studentDTO.marshall(student);
	return studentDTO;
    }

    @Override
    public StudentDTO remove(Long id) {
	Student student = studentDAO.find(id);
	StudentDTO studentDTO = new StudentDTO();
	studentDTO.marshall(student);
	studentDAO.remove(student);
	return studentDTO;
    }

    @Override
    public StudentDTO find(Long id) {
	Student student = studentDAO.find(id);
	StudentDTO studentDTO = new StudentDTO();
	studentDTO.marshall(student);
	return studentDTO;
    }

    @Override
    public List<StudentDTO> findAll() {
	Collection<Student> students = studentDAO.findAll();
	List<StudentDTO> studentDTOList = new ArrayList<StudentDTO>();
	for (Student student : students) {
	    StudentDTO studentDTO = new StudentDTO();
	    studentDTO.marshall(student);
	    studentDTOList.add(studentDTO);
	}
	return studentDTOList;
    }

    @Override
    public StudentDTO findByLoginId(Long id) {
	Student student = studentDAO.findStudentByLoginId(id);
	StudentDTO studentDTO = new StudentDTO();
	studentDTO.marshall(student);
	return studentDTO;
    }

    @Override
    public AddressDTO findAddress(Long studentId) {
	Student student = studentDAO.find(studentId);
	Address address = student.getAddress();
	AddressDTO addressDTO = new AddressDTO();
	addressDTO.marshall(address);
	return addressDTO;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<PhoneDTO> findPhoneNumbers(Long studentId) {
	Student student = studentDAO.find(studentId);
	List<Phone> phoneList = (List<Phone>) student.getPhoneNumbers();
	List<PhoneDTO> phoneDTOList = new ArrayList<PhoneDTO>();
	for (Phone phone : phoneList) {
	    PhoneDTO phoneDTO = new PhoneDTO();
	    phoneDTO.marshall(phone);
	    phoneDTOList.add(phoneDTO);
	}
	return phoneDTOList;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<EmailDTO> findEmailIds(Long studentId) {
	Student student = studentDAO.find(studentId);
	List<Email> emailList = (List<Email>) student.getEmailIds();
	List<EmailDTO> emailDTOList = new ArrayList<EmailDTO>();
	for (Email email : emailList) {
	    EmailDTO emailDTO = new EmailDTO();
	    emailDTO.marshall(email);
	    emailDTOList.add(emailDTO);
	}
	return emailDTOList;
    }

    @Override
    public AddressDTO updateAddress(Long studentId, AddressDTO addressDTO) {
	Student student = studentDAO.find(studentId);
	Address address = null;
	if (student.getAddress() == null) {
	    address = new Address();
	} else {
	    address = student.getAddress();
	}
	addressDTO.unmarshall(address);
	student.setAddress(address);
	studentDAO.update(student);
	return addressDTO;
    }

    @SuppressWarnings("unchecked")
    @Override
    public PhoneDTO updatePhone(Long studentId, PhoneDTO phoneDTO) {
	Student student = studentDAO.find(studentId);
	List<Phone> phoneList = (List<Phone>) student.getPhoneNumbers();
	Phone phone = new Phone();
	phoneDTO.unmarshall(phone);
	if (phoneList.contains(phone)) {
	    phoneList.remove(phone);
	}
	phoneList.add(phone);
	student.setPhoneNumbers(phoneList);
	studentDAO.update(student);
	return phoneDTO;
    }

    @SuppressWarnings("unchecked")
    @Override
    public EmailDTO updateEmail(Long studentId, EmailDTO emailDTO) {
	Student student = studentDAO.find(studentId);
	List<Email> emailList = (List<Email>) student.getEmailIds();
	Email email = new Email();
	emailDTO.unmarshall(email);
	if (emailList.contains(email)) {
	    emailList.remove(email);
	}
	emailList.add(email);
	studentDAO.update(student);
	return emailDTO;
    }

}
